package ldh.im.fxgui.controller;

import javafx.beans.InvalidationListener;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import ldh.im.fxbase.cell.FilterableTreeItem;
import ldh.im.fxbase.cell.ObjectTreeCell;
import ldh.im.fxbase.pojo.User;
import ldh.im.fxbase.util.RegionUtil;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

public class UserTreeController implements Initializable {

    @FXML private TreeView<User> userTreeView;
    @FXML private TextField searchTextField;
    @FXML private Pane contentPane;

    private FilterableTreeItem<User> root = buildUserTreeItemRoot();
//    private ObservableList<TreeItem<User>> userDatas = FXCollections.observableArrayList();
//    private FilteredList<TreeItem<User>> filteredData = new FilteredList<>(userDatas, s -> true);

    private RegionUtil.FxmlBean<Node, UserInfoController> userInfoFxmlBean = null;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        userTreeView.setRoot(root);
        userTreeView.setShowRoot(false);
        userTreeView.setCellFactory(new ObjectTreeCell<>(u->{
            HBox hBox = new HBox(5);
            hBox.getStyleClass().add("user-tree-cell");
            hBox.setAlignment(Pos.CENTER_LEFT);

            Label label = new Label(u.getUserName());
            if (u.getHeadImg() != null) {
                ImageView imageView = new ImageView();
                imageView.setFitWidth(50);
                imageView.setFitHeight(50);
                imageView.setImage(new Image(u.getHeadImg()));
                hBox.getChildren().add(imageView);
            } else {
                hBox.setPadding(new Insets(3, 0, 8, 0));
            }
            hBox.getChildren().add(label);
            return hBox;
        }));

        searchTextField.textProperty().addListener((ob, o, n)->{
            String filter = searchTextField.getText().trim();
            if(filter == null || filter.length() == 0) {
                root.predicateProperty().set(s->true);
            } else {
                root.predicateProperty().set(s -> {
                    boolean isValue = s.getUserName().contains(filter);
                    return isValue;
                });
            }
        });

        userTreeView.getSelectionModel().selectedItemProperty().addListener((InvalidationListener) l->{
            TreeItem<User> userItem = userTreeView.getSelectionModel().getSelectedItem();
            if (userItem == null) return;
            if (userInfoFxmlBean == null) {
                userInfoFxmlBean = RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/UserInfoPage.fxml"));
                userInfoFxmlBean.getController().setUser(userItem.getValue());
                contentPane.getChildren().clear();
                contentPane.getChildren().add(userInfoFxmlBean.getNode());
            } else {
                userInfoFxmlBean.getController().setUser(userItem.getValue());
                contentPane.getChildren().clear();
                contentPane.getChildren().add(userInfoFxmlBean.getNode());
            }
        });


        root.getSourceChildren().addAll(loadTreeUsers(200));
//        root.getChildren().addAll();
    }

    private boolean doTreeFilter(TreeItem<User> s, String filter) {
        if (s.getValue().getUserName().contains(filter)) return true;
        for(TreeItem<User> child : s.getChildren()) {
            boolean isHave = doTreeFilter(child, filter);
            if (isHave) return true;
        }
        return false;
    }

    private FilterableTreeItem<User> buildUserTreeItemRoot() {
        User user = new User();
        user.setUserName("root");
        user.setHeadImg(this.getClass().getResource("/imgs/head.jpg").toExternalForm());
        FilterableTreeItem<User> root = new FilterableTreeItem<>(user);
        return root;
    }

    private List<FilterableTreeItem<User>> loadUsers(int num, int t) {
        List<FilterableTreeItem<User>> users = new ArrayList();
        if (num > 30) {
            int n1 = (int) (Math.random() * 50);
            int tt = t;
            for(int i=0; i<n1; i++) {
                User user = new User();
                user.setUserName("demo " + (tt + i));
                user.setHeadImg(this.getClass().getResource("/imgs/head.jpg").toExternalForm());
                FilterableTreeItem ci = new FilterableTreeItem<>(user);
                if (i == 0) {
                    user.setHeadImg(null);
                    int n2 = num-n1;
                    for(int j=0;j<n2; j++) {
                        User user2 = new User();
                        user2.setUserName("demo " + (tt + i+j));
                        user2.setHeadImg(this.getClass().getResource("/imgs/head.jpg").toExternalForm());
                        ci.getSourceChildren().add(new FilterableTreeItem<>(user2));
                    }
                    tt += n2;
                }
                users.add(ci);
            }
        } else {
            for(int i=0; i<num; i++) {
                User user = new User();
                user.setUserName("demo " + (t + i));
                user.setHeadImg(this.getClass().getResource("/imgs/head.jpg").toExternalForm());
                users.add(new FilterableTreeItem<>(user));
            }
        }

        return users;
    }

    private List<FilterableTreeItem<User>> loadTreeUsers(int num) {
        List<FilterableTreeItem<User>> users = new ArrayList();
        int total = 0;
        for(int i=0; i<num; i++) {
            User user = new User();
            user.setUserName("group " + i);
//            user.setHeadImg(this.getClass().getResource("/imgs/head.jpg").toExternalForm());
            FilterableTreeItem<User> userFilterableTreeItem = new FilterableTreeItem<>(user);
            users.add(userFilterableTreeItem);

            int t = (int) (Math.random() * 100);
            t = t < 1 ? 10 : t;
            userFilterableTreeItem.getSourceChildren().addAll(loadUsers(t, total));
            total += t;
        }
        return users;
    }
}
